 var capturedPoint = null;
 var capturedType = "none";
 var capturedReference = null;
 var prevX = 0;
 var prevY = 0;


 function hasTouch() {
   return (('ontouchstart' in window) ||
     (navigator.maxTouchPoints > 0) ||
     (navigator.msMaxTouchPoints > 0));
 }

 if (hasTouch()) {
   canvas.addEventListener("touchstart", function(e) {
     e.preventDefault();
     if (e.stopPropagation) { e.stopPropagation() }
     e = e.targetTouches[0];
     down(e);
   }, false);

   canvas.addEventListener("touchmove", function(e) {
     e.preventDefault();
     if (e.stopPropagation) { e.stopPropagation() }
     move(e.changedTouches[0]);
   }, false);

   canvas.addEventListener("touchend", function(e) {
     e.preventDefault();
     if (e.stopPropagation) { e.stopPropagation() }
     capturedPoint = null;
   }, false);

   canvas.addEventListener("touchcancel", function(e) {
     e.preventDefault();
     if (e.stopPropagation) { e.stopPropagation() }
     capturedPoint = null;
   }, false);

 } else {

   canvas.addEventListener("mouseup", function(e) {
     e.preventDefault();
     if (e.stopPropagation) { e.stopPropagation() }
     capturedPoint = null;
   }, false);

   canvas.addEventListener("mousedown", function(e) {
     e.preventDefault();
     if (e.stopPropagation) { e.stopPropagation() }
     down(e);
   }, false);

   canvas.addEventListener("mousemove", function(e) {
     e.preventDefault();
     if (e.stopPropagation) { e.stopPropagation() }
     move(e);
   }, false);
 }

 function down(e) {

   var r = e.target.getClientRects()[0];
   var x = e.offsetX || (e.clientX - (r.x || r.left));
   var y = e.offsetY || (e.clientY - (r.y || r.top));

   if (lines && sizePoints) {
     for (var i = 0; i < sizePoints.length; i++) {
       if (Point.Sub(sizePoints[i].point, new Point(x, y)).length() < 15) {
         capturedPoint = new Point(sizePoints[i].point.x, sizePoints[i].point.y);
         prevX = x;
         prevY = y;
         capturedReference = sizePoints[i].reference;
         capturedType = "size";
         return;
       }
     }
   }

   for (var i = 0; i < points.length; i++) {
     if (Point.Sub(points[i], new Point(x, y)).length() < 15) {
       capturedPoint = points[i];
       capturedType = "move";
       prevX = x;
       prevY = y;
       return;
     }
   }

   capturedPoint = null;

 }

 function move(e) {

   if (!capturedPoint) {
     return;
   }

   var r = e.target.getClientRects()[0];
   var x = e.offsetX || (e.clientX - (r.x || r.left));
   var y = e.offsetY || (e.clientY - (r.y || r.top));

   capturedPoint.x += x - prevX;
   capturedPoint.y += y - prevY;

   if (lines && capturedType === "size") {
     var nv = Point.Sub(new Point(capturedPoint.x, capturedPoint.y), capturedReference);
     var s = Math.cos(Point.Angle(nv, Point.Sub(capturedPoint, capturedReference))) * nv.length();
     lineWidth = Math.abs(2 * s);
   }

   prevX = x;
   prevY = y;

   redraw();

 }

 document.getElementById("cap").onchange = function(e) {
   lineCap = e.target[e.target.selectedIndex].value;
   redraw();
 };
 document.getElementById("join").onchange = function(e) {
   lineJoin = e.target[e.target.selectedIndex].value;
   redraw();
 };
 document.getElementById("miter").onchange = function(e) {
   miterLimit = parseInt(e.target[e.target.selectedIndex].value);
   redraw();
 };
 document.getElementById("lines").onclick = function(e) {
   lines = e.target.checked;
   redraw();
 };
 document.getElementById("canvas").onclick = function(e) {
   drawWithCanvas = e.target.checked;
   redraw();
 };
